﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CoreCms.Net.Caching.AccressToken;
using CoreCms.Net.Configuration;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Utility.Extensions;
using CoreCms.Net.Utility.Helper;
using CoreCms.Net.WeChat.Service.HttpClients;
using InitQ.Abstractions;
using InitQ.Attributes;
using Newtonsoft.Json;
using SKIT.FlurlHttpClient.Wechat.Api;
using SKIT.FlurlHttpClient.Wechat.Api.Models;

namespace CoreCms.Net.RedisMQ
{
    /// <summary>
    /// 微信支付成功后推送到接口进行发货处理
    /// </summary>
    public class WeChatPayShippingSubscribe : IRedisSubscribe
    {
        private readonly IWeChatApiHttpClientFactory _weChatApiHttpClientFactory;
        private readonly ICoreCmsServicesServices _servicesServices;
        private readonly ICoreCmsBillPaymentsServices _billPaymentsServices;
        private readonly ICoreCmsBillDeliveryServices _billDeliveryServices;
        private readonly ICoreCmsOrderItemServices _orderItemServices;
        private readonly ICoreCmsUserServices _userServices;
        private readonly ICoreCmsUserWeChatInfoServices _weChatInfoServices;
        private readonly ICoreCmsOrderServices _orderServices;
        private readonly ICoreCmsSettingServices _settingServices;



        public WeChatPayShippingSubscribe(ICoreCmsBillPaymentsServices billPaymentsServices, IWeChatApiHttpClientFactory weChatApiHttpClientFactory, ICoreCmsServicesServices servicesServices, ICoreCmsBillDeliveryServices billDeliveryServices, ICoreCmsOrderItemServices orderItemServices, ICoreCmsUserServices userServices, ICoreCmsUserWeChatInfoServices weChatInfoServices, ICoreCmsOrderServices orderServices, ICoreCmsSettingServices settingServices)
        {
            _billPaymentsServices = billPaymentsServices;
            _weChatApiHttpClientFactory = weChatApiHttpClientFactory;
            _servicesServices = servicesServices;
            _billDeliveryServices = billDeliveryServices;
            _orderItemServices = orderItemServices;
            _userServices = userServices;
            _weChatInfoServices = weChatInfoServices;
            _orderServices = orderServices;
            _settingServices = settingServices;
        }

        /// <summary>
        /// 微信支付成功后推送到接口进行发货处理
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        [Subscribe(RedisMessageQueueKey.WeChatPayShipping)]
        private async Task WeChatPayNotice(string msg)
        {
            try
            {
                var paymentOrder = await _billPaymentsServices.QueryByClauseAsync(p => p.paymentId == msg);
                if (paymentOrder == null)
                {
                    NLogUtil.WriteAll(NLog.LogLevel.Info, LogType.RedisMessageQueue, "微信发货信息处理", msg + "：支付单不存在");
                    return;
                }
                else
                {
                    if (paymentOrder.paymentCode != GlobalEnumVars.PaymentsTypes.wechatpay.ToString())
                    {
                        NLogUtil.WriteAll(NLog.LogLevel.Info, LogType.RedisMessageQueue, "微信发货信息处理", msg + "：非微信支付方式不予处理");
                        return;
                    }




                    var client = _weChatApiHttpClientFactory.CreateWxOpenClient();
                    var accessToken = WeChatCacheAccessTokenHelper.GetWxOpenAccessToken();

                    var isTradeManagedRequest = new WxaSecOrderIsTradeManagedRequest()
                    {
                        AccessToken = accessToken
                    };
                    //商品名称
                    var orderTitle = string.Empty;
                    //检索是否开启了微信发货信息功能，才会进行后面的发货操作
                    var responseIsTradeManagedResponse = await client.ExecuteWxaSecOrderIsTradeManagedAsync(isTradeManagedRequest);
                    if (responseIsTradeManagedResponse.IsSuccessful() && responseIsTradeManagedResponse.IsTradeManaged)
                    {
                        //判断不同支付单类型下如何获取商品标题，目前只是简单标题，非商品订单如果需要详细到具体明细，建议扩展获取其他关联信息。
                        switch (paymentOrder.type)
                        {
                            case (int)GlobalEnumVars.BillPaymentsType.Recharge:
                                orderTitle = "用户充值" + paymentOrder.money + "元";
                                break;
                            case (int)GlobalEnumVars.BillPaymentsType.FormOrder:
                                orderTitle = "表单订单";
                                break;
                            case (int)GlobalEnumVars.BillPaymentsType.FormPay:
                                orderTitle = "表单付款码支付";
                                break;
                            case (int)GlobalEnumVars.BillPaymentsType.ServiceOrder:
                                {
                                    var id = Convert.ToInt32(paymentOrder.sourceId);
                                    var serviceModel = await _servicesServices.QueryByClauseAsync(p => p.id == id);
                                    if (serviceModel == null)
                                    {
                                        NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "微信发货信息处理", msg + "：服务项目获取失败");
                                        return;
                                    }
                                    orderTitle = serviceModel.title;
                                    break;
                                }
                            case (int)GlobalEnumVars.BillPaymentsType.Common:
                            case (int)GlobalEnumVars.BillPaymentsType.PinTuan:
                            case (int)GlobalEnumVars.BillPaymentsType.Group:
                            case (int)GlobalEnumVars.BillPaymentsType.Seckill:
                            case (int)GlobalEnumVars.BillPaymentsType.Solitaire:
                                {
                                    var orderItems = await _orderItemServices.QueryListByClauseAsync(p => p.orderId == paymentOrder.sourceId);
                                    if (!orderItems.Any())
                                    {
                                        NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "微信发货信息处理", msg + "：订单详情获取失败");
                                        return;
                                    }

                                    if (orderItems.Count == 1)
                                    {
                                        orderTitle = orderItems.FirstOrDefault()?.name;
                                    }
                                    else
                                    {
                                        orderItems.ForEach(p => { orderTitle += p.name + ";"; });
                                    }

                                    break;
                                }
                            case (int)GlobalEnumVars.BillPaymentsType.Bargain:
                                orderTitle = "砍价活动";
                                break;
                            case (int)GlobalEnumVars.BillPaymentsType.Giveaway:
                                orderTitle = "购物赠品";
                                break;
                            default:
                                NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "微信发货信息处理", msg + "：订单类型获取失败");
                                return;
                        }


                        //构建请求
                        var request = new WxaSecOrderUploadShippingInfoRequest
                        {
                            AccessToken = accessToken,
                            OrderKey = new WxaSecOrderUploadCombinedShippingInfoRequest.Types.OrderKey()
                            {
                                OrderNumberType = 2,
                                TransactionId = paymentOrder.tradeNo,
                            },
                            IsFinishAll = true
                        };


                        //组装参数

                        //获取openid
                        var user = await _userServices.QueryByClauseAsync(p => p.id == paymentOrder.userId);
                        if (user == null)
                        {
                            NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "微信发货信息处理", msg + "：用户信息获取失败");
                            return;
                        }

                        var weChatUserInfo = await _weChatInfoServices.QueryByClauseAsync(p => p.userId == user.id && p.type == (int)GlobalEnumVars.UserAccountTypes.微信小程序);
                        if (weChatUserInfo == null)
                        {
                            NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "微信发货信息处理", msg + "：用户信息openId获取失败");
                            return;
                        }

                        request.Payer = new WxaSecOrderUploadCombinedShippingInfoRequest.Types.Payer() { OpenId = weChatUserInfo.openid };

                        //设置发货信息
                        //如果是商品模式是，则去走快递或者自提及同城配送。
                        //两种情况：1支付单支付成功后，自动调用此模式处理充值，服务商品，用户自提的订单，2、如果是后台手动发货，处理发货的订单业务。
                        var shippingList = new List<WxaSecOrderUploadShippingInfoRequest.Types.Shipping>();

                        if (paymentOrder.type == (int)GlobalEnumVars.BillPaymentsType.Common
                            || paymentOrder.type == (int)GlobalEnumVars.BillPaymentsType.PinTuan
                            || paymentOrder.type == (int)GlobalEnumVars.BillPaymentsType.Group
                            || paymentOrder.type == (int)GlobalEnumVars.BillPaymentsType.Seckill
                            || paymentOrder.type == (int)GlobalEnumVars.BillPaymentsType.Solitaire)
                        {
                            //获取订单
                            var order = await _orderServices.QueryByClauseAsync(p => p.orderId == paymentOrder.sourceId);
                            if (order == null)
                            {
                                NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "微信发货信息处理", msg + "：订单获取失败");
                                return;
                            }

                            request.LogisticsType = order.receiptType switch
                            {
                                //设置物流的发货模式
                                (int)GlobalEnumVars.OrderReceiptType.SelfDelivery => (int)GlobalEnumVars.WeChatShippingLogisticsType.用户自提,
                                (int)GlobalEnumVars.OrderReceiptType.IntraCityService => (int)GlobalEnumVars.WeChatShippingLogisticsType.同城配送,
                                (int)GlobalEnumVars.OrderReceiptType.Logistics => (int)GlobalEnumVars.WeChatShippingLogisticsType.物流配送,
                                _ => request.LogisticsType
                            };

                            //判断订单是否发货
                            if (order.shipStatus is (int)GlobalEnumVars.OrderShipStatus.PartialYes or (int)GlobalEnumVars.OrderShipStatus.Yes)
                            {
                                //获取订单的发货信息
                                var orderBillDeliveries = await _billDeliveryServices.QueryListByClauseAsync(p => p.orderId == paymentOrder.sourceId);
                                if (orderBillDeliveries == null || !orderBillDeliveries.Any())
                                {
                                    NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "微信发货信息处理", msg + "：未获取到发货信息，自动发货停止操作");
                                    return;
                                }
                                shippingList.AddRange(orderBillDeliveries.Select(item => new WxaSecOrderUploadShippingInfoRequest.Types.Shipping { ItemDescription = orderTitle, ExpressCompany = item.thirdPartylogiCode, TrackingNumber = item.logiNo }));

                                request.DeliveryMode = orderBillDeliveries.Count > 1
                                    ? (int)GlobalEnumVars.WeChatShippingDeliveryMode.SPLIT_DELIVERY
                                    : (int)GlobalEnumVars.WeChatShippingDeliveryMode.UNIFIED_DELIVERY;
                            }
                            else
                            {
                                //判断是否门店订单自动发货
                                var allConfigs = await _settingServices.GetConfigDictionaries();
                                var storeOrderAutomaticDelivery = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.StoreOrderAutomaticDelivery).ObjectToInt(1);
                                if (storeOrderAutomaticDelivery == 1 || order.receiptType == (int)GlobalEnumVars.OrderReceiptType.SelfDelivery)
                                {
                                    shippingList.Add(new WxaSecOrderUploadShippingInfoRequest.Types.Shipping() { ItemDescription = orderTitle, ExpressCompany = "", TrackingNumber = "" });
                                }
                                else
                                {
                                    NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "微信发货信息处理", msg + "：未获取到发货信息，自动发货停止操作");
                                    return;
                                }
                            }
                        }
                        else
                        {
                            //非商品模式，直接走虚拟发货。
                            request.LogisticsType = (int)GlobalEnumVars.WeChatShippingLogisticsType.虚拟商品;
                            request.DeliveryMode = (int)GlobalEnumVars.WeChatShippingDeliveryMode.UNIFIED_DELIVERY;
                            shippingList.Add(new WxaSecOrderUploadShippingInfoRequest.Types.Shipping() { ItemDescription = orderTitle, ExpressCompany = "", TrackingNumber = "" });
                        }

                        request.ShippingList = shippingList;

                        var response = await client.ExecuteWxaSecOrderUploadShippingInfoAsync(request);
                        if (response.IsSuccessful())
                        {
                            NLogUtil.WriteAll(NLog.LogLevel.Info, LogType.RedisMessageQueue, "微信发货信息处理", msg + ":发货提交成功");
                        }
                        else
                        {
                            NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "微信发货信息处理-推送接口", JsonConvert.SerializeObject(response));

                        }
                    }
                    else
                    {
                        NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "微信发货信息处理-获取是否需要推送", JsonConvert.SerializeObject(responseIsTradeManagedResponse));
                    }
                }
            }
            catch (Exception ex)
            {
                NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "微信发货信息处理", msg, ex);
                throw;
            }
            await Task.CompletedTask;
        }

    }
}
